package com.fast.controller.delay;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author hujw
 * @since 2022/1/25
 */
@RestController
@RequestMapping("/delay")
@Api(tags = "延时队列测试")
@Slf4j
public class DelayController {
    private DelayQueue<Order> delayQueue = new DelayQueue<>();
    @Resource
    private ThreadPoolExecutor resultThreadPool;
    @Autowired
    private ApplicationContext applicationContext;

    @GetMapping("/{num}")
    @ApiOperation("延时队列测试")
    public String delay(@PathVariable("num") int num) throws Exception {
        for (int i = 1; i <= num; i++) {
            //1.提交任务
            DelayTask delayTask = applicationContext.getBean(DelayTask.class);
            delayTask.setSid("sid-" + i);
            delayTask.setNsrsbh("nsrsbh-" + i);
            delayTask.setI(i);
            resultThreadPool.submit(delayTask);
            delayQueue.put(new Order("test" + i, 5, TimeUnit.SECONDS, "nsrsbh-" + i));
        }


        Thread thread = new Thread(() -> {
            int count = 0;
            while (delayQueue.size() != 0) {
                /**
                 * 取队列头部元素是否过期
                 */
                Order task = delayQueue.poll();
                if (task != null) {
                    //2.查询任务执行结果
                    System.out.format("队列:{%s}执行, 参数:{%s},时间:{%s}\n", task.name, task.nsrsbh, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    if (task.name.endsWith("10")) {
                        if (count == 3) {
                            log.error("队列:{}执行出错", task.name);
                            continue;
                        }
                        //3.如果任务执行失败，继续放入延时队列，尝试三次，如果仍然失败，打印错误日志记录
                        delayQueue.put(new Order("test---" + 10, 5, TimeUnit.SECONDS, "nsrsbh-+" + 10));
                        count++;
                    }
                }
            }
        });
        thread.start();
        return "主线程执行完成";
    }
}
